#import "LibCloudStoragePlugin.h"
#import "GoogleAuthenticator.h"
#import "GoogleCloudStorage.h"

@implementation LibCloudStoragePlugin

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                     methodChannelWithName:@"lib_cloud_storage"
                                     binaryMessenger:[registrar messenger]];
    LibCloudStoragePlugin* instance = [[LibCloudStoragePlugin alloc] init];
    [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    
    NSLog(@"call.method %@", call.method);
    NSDictionary *arguments = [LibCloudStoragePlugin convertJsonToDictionary:call.arguments];
    
    if ([call.method isEqualToString:@"uploadToGoogleCloud"]) {
        
        NSString *fileName = [NSString stringWithFormat:@"%@_fvvewr",arguments[@"fileName"]];
        NSString *content = arguments[@"fileContent"];
        NSLog(@"fileName= %@",fileName);
        NSLog(@"content= %@",content);
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
          
        if (fileName && content) {
            
            NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileName];
            if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
                [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
            }
            NSError *writeError = nil;
            [content writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&writeError];
            if (writeError) {
                [dict setValue:@-1 forKey:@"code"];
                [dict setValue:@"Description Failed to write the file to the local" forKey:@"error"];
                result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
                return;
            }
            NSLog(@"filePath= %@",filePath);
            
            [GoogleCloudStorage uploadFileAtPath:filePath progress:nil completion:^(GTLRDrive_File * _Nullable file, NSError * _Nullable error) {
                
                if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
                    [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
                }
                NSLog(@"%@",file);
                NSLog(@"%@",error);
                
                if (error) {
                    [dict setValue:error.localizedFailureReason forKey:@"error"];
                    [dict setValue:@-1 forKey:@"code"];
                } else {
                    [dict setValue:file.identifier forKey:@"fileId"];
                    [dict setValue:@0 forKey:@"code"];
                }
                result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
            }];
        } else {
            [dict setValue:@-1 forKey:@"code"];
            [dict setValue:@"parameter error" forKey:@"error"];
            result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
        }
        return;
    }
    
    if ([call.method isEqualToString:@"google_drive_download"]) {
        
        NSString *fileId = arguments[@"fileId"];
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        
        if (fileId) {
            [GoogleCloudStorage readFile:fileId completion:^(NSData * _Nullable fileData, NSError * _Nullable error) {
                if (error) {
                    [dict setValue:error.localizedFailureReason forKey:@"error"];
                    [dict setValue:@-1 forKey:@"code"];
                } else {
                    NSString *content = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];
                    [dict setValue:content forKey:@"fileContent"];
                    [dict setValue:@0 forKey:@"code"];
                }
                result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
            }];
        } else {
            [dict setValue:@-1 forKey:@"code"];
            [dict setValue:@"parameter error" forKey:@"error"];
            result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
        }
        return;
    }
    
    if ([call.method isEqualToString:@"google_login_sign"]) {
        
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        NSString *clientID = arguments[@"clientID"];
        
        UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;;
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for (UIWindow *window in windows) {
            if (rootViewController) {
                break;
            }
            rootViewController = window.rootViewController;
        }
        
        if (rootViewController) {
            [GoogleAuthenticator signInWithClientID:clientID presentingViewController:rootViewController completion:^(GIDGoogleUser * _Nonnull user, NSError * _Nonnull error) {
                
                if (error) {
                    [dict setValue:error.localizedFailureReason forKey:@"error"];
                    [dict setValue:@-1 forKey:@"code"];
                } else {
                    [dict setValue:user.profile.email forKey:@"email"];
                    [dict setValue:user.idToken.tokenString forKey:@"idToken"];
                    [dict setValue:[NSString stringWithFormat:@"%.f", user.idToken.expirationDate.timeIntervalSince1970] forKey:@"expirationDate"];
                    [dict setValue:@0 forKey:@"code"];
                }
                result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
            }];
        } else {
            [dict setValue:@-1 forKey:@"code"];
            [dict setValue:@"Failed to get controller" forKey:@"error"];
            result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
        }
        return;
    }
    
    if ([call.method isEqualToString:@"google_drive_file_list"]) {
        
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        NSString *fileName = arguments[@"prefix"];
        if (fileName) {
            [GoogleCloudStorage fetchFileListCompletion:^(GTLRDrive_FileList * _Nullable files, NSError * _Nullable error) {
                if (error) {
                    [dict setValue:error.localizedFailureReason forKey:@"error"];
                    [dict setValue:@-1 forKey:@"code"];
                } else {
                    NSMutableArray *fileList = [NSMutableArray array];
                    for (GTLRDrive_File *file in files) {
                        [fileList addObject:@{
                            @"fileName": file.name,
                            @"fileId": file.identifier
                        }];
                    }
                    [dict setValue:fileList forKey:@"fileList"];
                    [dict setValue:@0 forKey:@"code"];
                }
                result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
            }];
        } else {
            [dict setValue:@-1 forKey:@"code"];
            [dict setValue:@"parameter error" forKey:@"error"];
            result([LibCloudStoragePlugin convertDictionaryToJson:dict]);
        }
        return;
    }
    result(FlutterMethodNotImplemented);
}

+ (NSString *)convertDictionaryToJson:(NSDictionary *)dictionary {
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
                                                       options:NSJSONWritingPrettyPrinted
                                                         error:&error];
    if (!jsonData) {
        return nil;
    }
    
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    return jsonString;
}


+ (NSDictionary *)convertJsonToDictionary:(NSString *)jsonString {
    NSError *error;
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    
    if (!jsonData) {
        return nil;
    }
    
    id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                    options:NSJSONReadingMutableContainers
                                                      error:&error];
    
    if ([jsonObject isKindOfClass:[NSDictionary class]]) {
        return (NSDictionary *)jsonObject;
    } else {
        return nil;
    }
}



@end
